class ChatApp {
    constructor() {
        this.initElements();
        this.initState();
        this.bindEvents();
        this.initialize();
    }

    initElements() {
        this.elements = {
            sidebar: document.getElementById('sidebar'),
            chatList: document.getElementById('chatList'),
            chatContainer: document.getElementById('chatContainer'),
            welcomeScreen: document.getElementById('welcomeScreen'),
            messageInput: document.getElementById('messageInput'),
            sendButton: document.getElementById('sendButton'),
            newChatBtn: document.getElementById('newChatBtn'),
            toggleSidebarBtn: document.getElementById('toggleSidebarBtn'),
            restoreSidebarBtn: document.getElementById('restoreSidebarBtn'),
            loadingSpinner: document.getElementById('loadingSpinner'),
            toast: document.getElementById('toast'),
            modelSelect: document.getElementById('modelSelect')
        };

        Object.entries(this.elements).forEach(([key, element]) => {
            if (!element) {
                console.error(`Element not found: ${key}`);
            }
        });
    }

    initState() {
        this.state = {
            currentConversationId: null,
            isProcessing: false,
            conversations: new Map(),
            sidebarHidden: localStorage.getItem('sidebarHidden') === 'true',
            messageHistory: []
        };
    }

    bindEvents() {
        this.elements.toggleSidebarBtn?.addEventListener('click', (e) => {
            e.stopPropagation();
            this.toggleSidebar();
        });

        this.elements.restoreSidebarBtn?.addEventListener('click', (e) => {
            e.stopPropagation();
            if (this.state.sidebarHidden) {
                this.toggleSidebar();
            }
        });

        this.elements.newChatBtn?.addEventListener('click', (e) => {
            e.stopPropagation();
            this.createNewConversation();
        });

        this.elements.sendButton?.addEventListener('click', () => {
            this.handleSendMessage();
        });

        if (this.elements.messageInput) {
            this.elements.messageInput.addEventListener('input', () => {
                this.adjustTextareaHeight();
            });

            this.elements.messageInput.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                    e.preventDefault();
                    this.handleSendMessage();
                }
            });

            this.elements.messageInput.focus();
        }

        document.addEventListener('click', (e) => {
            if (window.innerWidth <= 768 && 
                !this.elements.sidebar?.contains(e.target) &&
                !this.elements.restoreSidebarBtn?.contains(e.target) &&
                !this.state.sidebarHidden) {
                this.toggleSidebar();
            }
        });
    }

    async initialize() {
        if (this.state.sidebarHidden && this.elements.sidebar) {
            this.elements.sidebar.classList.add('hidden');
        }

        // 加载模型列表
        await this.loadModels();

        try {
            const response = await fetch('/api/conversations');
            if (!response.ok) throw new Error('Failed to load conversations');
            
            const conversations = await response.json();
            conversations.forEach(conv => {
                conv.messages = conv.messages || [];
                this.state.conversations.set(conv.conversation_id, conv);
            });
            
            this.updateConversationList();
        } catch (error) {
            console.error('Error initializing:', error);
            this.showToast('初始化失败，请刷新页面重试');
        }
    }

    async loadModels() {
        try {
            const response = await fetch('/api/models');
            if (!response.ok) throw new Error("Failed to load model list");
            const data = await response.json();
            const modelSelect = this.elements.modelSelect;
            modelSelect.innerHTML = '';
            data.available_models.forEach(modelName => {
                const option = document.createElement('option');
                option.value = modelName;
                option.textContent = modelName;
                if (modelName === data.current_model) {
                    option.selected = true;
                }
                modelSelect.appendChild(option);
            });

            // 模型切换事件
            modelSelect.addEventListener('change', async (e) => {
                const selectedModel = e.target.value;
                await this.setModel(selectedModel);
            });
        } catch (e) {
            console.error("Error loading models:", e);
            this.showToast("加载模型列表失败");
        }
    }

    async setModel(modelName) {
        try {
            const response = await fetch('/api/models', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ model_name: modelName })
            });
            if (!response.ok) throw new Error("Failed to set model");
            const data = await response.json();
            this.showToast("模型已更新为：" + modelName);
            // 可根据需要在这里刷新当前对话或列表
        } catch (e) {
            console.error("Error setting model:", e);
            this.showToast("设置模型失败，请重试");
        }
    }

    async createNewConversation() {
        try {
            this.showLoading();
            const response = await fetch('/api/conversations', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'application/json'
                }
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(errorData.message || '创建对话失败');
            }

            const conversation = await response.json();
            conversation.messages = conversation.messages || [];
            this.state.conversations.set(conversation.conversation_id, conversation);
            this.state.currentConversationId = conversation.conversation_id;
            
            await this.switchToConversation(conversation.conversation_id);
            this.updateConversationList();
            
        } catch (error) {
            console.error('Error creating conversation:', error);
            this.showToast(error.message || '创建对话失败，请重试');
        } finally {
            this.hideLoading();
        }
    }

    async handleSendMessage() {
        if (this.state.isProcessing || !this.elements.messageInput) return;

        const message = this.elements.messageInput.value.trim();
        if (!message) return;

        this.state.isProcessing = true;
        this.elements.messageInput.value = '';
        this.adjustTextareaHeight();

        if (!this.state.currentConversationId) {
            await this.createNewConversation();
        }

        const currentConv = this.state.conversations.get(this.state.currentConversationId);
        if (!currentConv) {
            console.error("No current conversation found after creation");
            this.state.isProcessing = false;
            return;
        }

        // 添加用户消息到UI和内存数据
        this.appendMessage(message, 'user', true);

        try {
            const response = await fetch('/api/chat', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({
                    message,
                    conversation_id: this.state.currentConversationId
                })
            });

            if (!response.ok) throw new Error('发送消息失败');

            const reader = response.body.getReader();
            let assistantMessage = '';
            while (true) {
                const {value, done} = await reader.read();
                if (done) break;
                const text = new TextDecoder().decode(value);
                assistantMessage += text;
                this.updateAssistantMessage(assistantMessage, false);
            }

            const updatedConv = this.state.conversations.get(this.state.currentConversationId);
            if (updatedConv) {
                updatedConv.messages.push({role: 'assistant', content: assistantMessage});
                this.state.conversations.set(this.state.currentConversationId, updatedConv);
            }

        } catch (error) {
            console.error('Error sending message:', error);
            this.showToast('发送消息失败，请重试');
        } finally {
            this.state.isProcessing = false;
            this.elements.messageInput.focus();

            // 完成后再次刷新当前对话数据，以确保标题和消息同步更新
            if (this.state.currentConversationId) {
                await this.refreshConversationData(this.state.currentConversationId);
                this.switchToConversation(this.state.currentConversationId);
            }
        }
    }

    async switchToConversation(conversationId) {
        this.state.currentConversationId = conversationId;
        await this.refreshConversationData(conversationId);

        const conversation = this.state.conversations.get(conversationId);
        if (!conversation) {
            this.elements.chatContainer.style.display = 'none';
            this.elements.welcomeScreen.style.display = 'flex';
            return;
        }

        this.elements.welcomeScreen.style.display = 'none';
        this.elements.chatContainer.style.display = 'block';
        this.elements.chatContainer.innerHTML = '';
        this.elements.messageInput.focus();

        if (conversation.messages) {
            conversation.messages.forEach(msg => {
                this.appendMessage(msg.content, msg.role, false);
            });
        }
    }

    async refreshConversationData(conversationId) {
        try {
            const convResponse = await fetch(`/api/conversations/${conversationId}`, {
                method: 'GET',
                headers: { 'Accept': 'application/json' }
            });
            if (convResponse.ok) {
                const freshConv = await convResponse.json();
                freshConv.messages = freshConv.messages || [];
                this.state.conversations.set(conversationId, freshConv);
                this.updateConversationList();
            }
        } catch (e) {
            console.error("Failed to refresh conversation data:", e);
        }
    }

    appendMessage(content, role, updateState = false) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${role}`;
        messageDiv.innerHTML = `
            <div class="message-wrapper">
                <div class="message-avatar">
                    ${role === 'user' ? '<i class="fas fa-user"></i>' : '<i class="fas fa-robot"></i>'}
                </div>
                <div class="message-content">${this.formatMessage(content)}</div>
            </div>
        `;
        this.elements.chatContainer.appendChild(messageDiv);
        this.scrollToBottom();

        if (updateState && this.state.currentConversationId) {
            const conv = this.state.conversations.get(this.state.currentConversationId);
            if (conv) {
                conv.messages.push({role, content});
                this.state.conversations.set(this.state.currentConversationId, conv);
            }
        }

        return messageDiv;
    }

    updateAssistantMessage(content) {
        let messageDiv = this.elements.chatContainer.querySelector('.message.assistant:last-child');
        if (!messageDiv) {
            messageDiv = this.appendMessage(content, 'assistant', false);
        } else {
            messageDiv.querySelector('.message-content').innerHTML = this.formatMessage(content);
        }
        this.scrollToBottom();
    }

    formatMessage(content) {
        return content
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\n/g, '<br>')
            .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
            .replace(/\*(.*?)\*/g, '<em>$1</em>');
    }

    updateConversationList() {
        if (!this.elements.chatList) return;

        this.elements.chatList.innerHTML = '';
        const allConversations = Array.from(this.state.conversations.values()).reverse();
        allConversations.forEach(conv => {
            const item = document.createElement('div');
            item.className = `chat-item${conv.conversation_id === this.state.currentConversationId ? ' active' : ''}`;

            let displayTitle = conv.title || '新对话';
            if (!displayTitle && conv.messages && conv.messages.length > 0) {
                displayTitle = conv.messages[0].content.slice(0, 20) + (conv.messages[0].content.length > 20 ? '...' : '');
            } else if (!displayTitle) {
                displayTitle = '新对话';
            }

            item.innerHTML = `
                <span class="chat-item-title">${displayTitle}</span>
                <button class="download-btn" title="下载对话">
                    <i class="fas fa-download"></i>
                </button>
                <button class="delete-btn" title="删除对话">
                    <i class="fas fa-trash"></i>
                </button>
            `;

            item.addEventListener('click', (e) => {
                if (!e.target.closest('.download-btn, .delete-btn')) {
                    this.switchToConversation(conv.conversation_id);
                }
            });

            const downloadBtn = item.querySelector('.download-btn');
            if (downloadBtn) {
                downloadBtn.addEventListener('click', (e) => {
                    e.stopPropagation();
                    this.downloadConversation(conv);
                });
            }

            const deleteBtn = item.querySelector('.delete-btn');
            if (deleteBtn) {
                deleteBtn.addEventListener('click', async (e) => {
                    e.stopPropagation();
                    if (confirm('确定要删除这个对话吗？')) {
                        await this.deleteConversation(conv.conversation_id);
                    }
                });
            }

            this.elements.chatList.appendChild(item);
        });
    }

    async deleteConversation(conversationId) {
        try {
            const response = await fetch(`/api/conversations/${conversationId}`, {
                method: 'DELETE'
            });

            if (!response.ok) throw new Error('删除对话失败');

            this.state.conversations.delete(conversationId);
            if (this.state.currentConversationId === conversationId) {
                this.state.currentConversationId = null;
                this.elements.chatContainer.style.display = 'none';
                this.elements.welcomeScreen.style.display = 'flex';
            }
            
            this.updateConversationList();
        } catch (error) {
            console.error('Error deleting conversation:', error);
            this.showToast('删除对话失败，请重试');
        }
    }

    downloadConversation(conversation) {
        const conv = this.state.conversations.get(conversation.conversation_id);
        const exportData = conv ? conv.messages.map(msg => ({
            role: msg.role,
            content: msg.content,
            timestamp: new Date().toISOString()
        })) : [];

        const blob = new Blob([JSON.stringify(exportData, null, 2)], { type: 'application/json' });
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        const dateStr = new Date().toLocaleDateString().replace(/\//g, '_');
        a.href = url;
        a.download = `对话记录_${dateStr}.json`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    }

    toggleSidebar() {
        if (!this.elements.sidebar) return;

        this.state.sidebarHidden = !this.state.sidebarHidden;
        this.elements.sidebar.classList.toggle('hidden');
        localStorage.setItem('sidebarHidden', this.state.sidebarHidden);

        const toggleIcon = this.elements.toggleSidebarBtn?.querySelector('i');
        if (toggleIcon) {
            toggleIcon.className = this.state.sidebarHidden ? 
                'fas fa-chevron-right' : 'fas fa-chevron-left';
        }
    }

    adjustTextareaHeight() {
        const textarea = this.elements.messageInput;
        if (!textarea) return;
        textarea.style.height = 'auto';
        textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
    }

    scrollToBottom() {
        if (this.elements.chatContainer) {
            this.elements.chatContainer.scrollTop = this.elements.chatContainer.scrollHeight;
        }
    }

    showToast(message, duration = 3000) {
        if (!this.elements.toast) return;
        
        this.elements.toast.textContent = message;
        this.elements.toast.style.display = 'block';
        setTimeout(() => {
            this.elements.toast.style.display = 'none';
        }, duration);
    }

    showLoading() {
        if (this.elements.loadingSpinner) {
            this.elements.loadingSpinner.style.display = 'block';
        }
    }

    hideLoading() {
        if (this.elements.loadingSpinner) {
            this.elements.loadingSpinner.style.display = 'none';
        }
    }
}

document.addEventListener('DOMContentLoaded', () => {
    window.chatApp = new ChatApp();
});
